import G6 from "@antv/g6";
import { render } from "vue";

import { emitter } from "@/utils/mitt";
import { edgeOptions } from "./state";
import { registerIcon } from "./customShape";
import { registerCircle } from "./circleShape";
import { createMenu } from "./plugin";
import { useCanvasStoreHook } from "@/stores/modules/canvas"; // 画布
import { useSelectGraphStoreHook } from "@/stores/modules/selectGraph"; // 画布
import ToolBar from "@/views/associationAnalysis/canvas/components/Affix/index.vue";

export const colorList = [
  "rgb(158, 213, 255)",
  "rgb(44, 150, 230)",
  "rgb(38, 175, 155)",
  "rgb(139, 232, 203)",
  "rgb(153, 204, 73)",
  "rgb(255, 220, 102)",
  "rgb(250, 194, 10)",
  "rgb(242, 145, 3)",
  "rgb(252, 134, 176)",
  "rgb(246, 111, 106)",
  "rgb(114, 112, 217)",
];

export let graph = null;
export let toolbar = null;

const useCanvasStore = useCanvasStoreHook(); // 画布
const useSelectGraphStore = useSelectGraphStoreHook(); // 画布

export const initGraph = () => {
  const container = document.getElementById("mountNode");
  const width = container.clientWidth || 1710;
  const height = container.clientHeight || 865;

  toolbar = new G6.ToolBar({
    className: "graph-toolbar-content",
    container: "graph-toolbar-content",
    getContent: () => {
      const container = document.createElement("div");
      render(h(ToolBar, graph), container);
      console.log(container, "container");
      return container;
    },
    handleClick: (code, graph) => {
      // console.log(1112222, toolbar);
      switch (code) {
        case "autoZoom":
          toolbar.autoZoom();
          break;
        case "zoomIn":
          toolbar.zoomIn();
          break;
        case "zoomOut":
          toolbar.zoomOut();
          break;
        case "move":
          emitter.emit("handleSelect", "drag-canvas");
          break;
        case "kuangxuan":
          emitter.emit("handleSelect", "brush-select");
          break;
      }
    },
  });
  //注册icon
  registerIcon();
  registerCircle();
  //创建菜单
  const menu = createMenu();
  //G6配置项
  graph = new G6.Graph({
    container: container,
    width,
    height,
    // fitCenter: true,
    modes: {
      default: [
        "drag-canvas",
        "zoom-canvas",
        "drag-node",
        {
          type: "activate-relations",
          inactiveState: "dark",
        },
        {
          type: "click-select",
          selectEdge: true,
        },
      ],
    },
    defaultNode: {
      size: 20,
      type: "circle",
      style: {
        stroke: "",
        lineWidth: 2,
      },
      labelCfg: {
        style: {
          fontSize: 14,
          fontWeight: 500,
          background: {
            padding: [2, 2, 2, 2],
            radius: 2,
          },
        },
        position: "bottom",
      },
    },
    defaultEdge: {
      type: "quadratic",
      style: {
        stroke: "rgb(153,153,153)",
        lineWidth: 2,
        endArrow: true,
        lineAppendWidth: 4,
      },
      labelCfg: {
        style: {
          fill: "#fff",
          background: {
            fill: "#ccc",
            padding: [2, 2, 3, 2],
            radius: 2,
          },
        },
        autoRotate: true,
      },
    },
    nodeStateStyles: {
      active: {
        lineWidth: 2,
        stroke: "#5F95FF",
        shadowColor: "#5F95FF",
        shadowBlur: 6,
        strokeOpacity: 0.6,
        cursor: "pointer",
      },
      selected: {
        lineWidth: 4,
        stroke: "#5F95FF",
        shadowColor: "#5F95FF",
        shadowBlur: 6,
        strokeOpacity: 0.8,
        cursor: "pointer",
        isHighLight: true,
      },
    },
    edgeStateStyles: {
      active: {
        lineWidth: 2,
        stroke: "#5F95FF",
        shadowColor: "#5F95FF",
        shadowBlur: 6,
        strokeOpacity: 0.6,
        cursor: "pointer",
      },
      dark: {
        opacity: 0.2,
      },
    },
    enabledStack: true,
    layout: {
      type: "force",
      animate: true,
      preventOverlap: true,
      nodeSize: 40,
      nodeStrength: 5,
      linkDistance: 150,
      nodeSpacing: (d) => {
        // 防止重叠时节点边缘间距的最小值;
        // console.log(d, "d");
        if (d.label.length > 12) {
          return 70;
        }
        return 40;
      },
    },
    // fitView: true,
    // fitViewPadding: 0,
    animate: true,
    animateCfg: {
      duration: 500, // Number，一次动画的时长
      easing: "easePolyOut", // String，动画函数
    },
    plugins: [toolbar, menu],
  });

  // 读取数据
  graph.render();

  graph.on("nodeselectchange", (e) => {
    console.log(e, "nodeselectchange", graph.getUndoStack());
    if (isPathSelect.value) {
      isPathSelect.value = false;
      // 路径分析选择节点不存到store
      emitter.emit("getPathSelectNode", e.selectedItems.nodes[0]);
      useSelectGraphStore.setSelectCanvas(null);
    } else {
      // 所有被选中的 items 集合
      if (
        e.selectedItems.nodes.length > 0 ||
        e.selectedItems.edges.length > 0
      ) {
        const data = {
          nodes: e.selectedItems.nodes.map((item) => item._cfg.model),
          edges: e.selectedItems.edges.map((item) => item._cfg.model),
        };

        graph.getNodes().forEach((node) => {
          graph.setItemState(node, "selected", false);
        });
        graph.getEdges().forEach((edge) => {
          graph.setItemState(edge, "selected", false);
        });
        e.selectedItems.nodes.forEach((item) => {
          graph.setItemState(item, "selected", true);
        });
        e.selectedItems.edges.forEach((item) => {
          graph.setItemState(item, "selected", true);
        });

        useSelectGraphStore.setSelectCanvas(data);
      } else {
        clearAllStats();
        useSelectGraphStore.setSelectCanvas(null);
      }
    }
  });

  const isPathSelect = ref(null); // 是否是路径分析选择节点
  emitter.on("pathSelectNode", () => {
    // 路径分析选择节点
    isPathSelect.value = true;
    clearAllStats();
    useSelectGraphStore.setSelectCanvas(null);
  });

  // 鼠标进入节点
  graph.on("node:mouseenter", (e) => {
    // console.log(e, "node:mouseenter");
    const nodeItem = e.item; // 获取鼠标进入的节点元素对象
    graph.setItemState(nodeItem, "active", true); // 设置当前节点的 hover 状态为 true
  });
  // // 鼠标离开节点
  graph.on("node:mouseleave", (e) => {
    // console.log(e, "node:mouseleave");
    const nodeItem = e.item; // 获取鼠标离开的节点元素对象
    graph.setItemState(nodeItem, "active", false); // 设置当前节点的 hover 状态为 false
  });

  graph.on("node:dragstart", function (e) {
    // console.log(e, "dragstart", graph.get("layoutController"));
    if (e.item.hasLocked()) return; // 锁定的节点不允许拖动
    if (graph.get("layoutController").layoutType != "force") return; // 不是力导布局的时候不执行后面的方法
    // if (graph.getNodes().length == 1) return; // 一个节点不执行后面方法
    const forceLayout = graph.get("layoutController").layoutMethods[0];
    // console.log(forceLayout, "forceLayout");
    forceLayout.destroy(); // 使用execute拖动节点会抖动
    // graph.layout();
    refreshDragedNodePosition(e);
  });

  graph.on("node:drag", function (e) {
    if (e.item.hasLocked()) return; // 锁定的节点不允许拖动
    if (graph.get("layoutController").layoutType != "force") return; // 不是力导布局的时候不执行后面的方法
    // if (graph.getNodes().length == 1) return; // 一个节点不执行后面方法
    graph.layout();
    // const forceLayout = graph.get("layoutController").layoutMethods[0];
    // forceLayout.execute();
    refreshDragedNodePosition(e);
  });

  graph.on("node:dragend", function (e) {
    if (graph.getNodes().length == 1) return; // 一个节点不执行后面方法
    e.item.get("model").fx = null;
    e.item.get("model").fy = null;
  });

  graph.on("dragnodeend", function (e) {
    // console.log(graph.getHulls(), "getHulls");
    if (graph.getHulls() && graph.getHulls()[1]) {
      // 节点拖动后需要根据节点位置重新渲染包裹区域，社区发现功能
      emitter.emit("communityDetection");
    }
  });

  // 鼠标进入节点
  graph.on("edge:mouseenter", (e) => {
    const edgeItem = e.item; // 获取鼠标进入的节点元素对象
    graph.setItemState(edgeItem, "active", true); // 设置当前节点的 hover 状态为 true
  });
  // // 鼠标离开节点
  graph.on("edge:mouseleave", (e) => {
    const edgeItem = e.item; // 获取鼠标离开的节点元素对象
    graph.setItemState(edgeItem, "active", false); // 设置当前节点的 hover 状态为 false
  });
  // graph.on("edge:click", (e) => {
  //   const edgeItem = e.item; // 获取鼠标进入的节点元素对象
  //   graph.setItemState(edgeItem, "selected", true); // 设置当前节点的 hover 状态为 true
  // });

  // //鼠标单击节点
  // graph.on("node:click", (evt) => {
  //   const { item } = evt;
  //   console.log(item, "item");
  //   graph.setAutoPaint(false);
  //   // graph.setItemState(item, "highlight", true);
  //   // graph.getNodes().forEach((node) => {
  //   //   graph.clearItemStates(node);
  //   //   graph.setItemState(node, "active", true);
  //   // });
  //   // graph.getEdges().forEach((edge) => {
  //   //   graph.clearItemStates(edge);
  //   //   graph.setItemState(edge, "lineDark", true);
  //   // });

  //   // graph.setItemState(item, "dark", false);
  //   // graph.setItemState(item, "highlight", true);
  //   // graph.getEdges().forEach(function (edge) {
  //   //   if (edge.getSource() === item) {
  //   //     graph.setItemState(edge.getTarget(), "dark", false);
  //   //     graph.setItemState(edge.getTarget(), "highlight", true);
  //   //     graph.setItemState(edge, "lineDark", false);
  //   //     graph.setItemState(edge, "highlight", true);
  //   //     edge.toFront();
  //   //   } else if (edge.getTarget() === item) {
  //   //     graph.setItemState(edge.getSource(), "dark", false);
  //   //     graph.setItemState(edge.getSource(), "highlight", true);
  //   //     graph.setItemState(edge, "lineDark", false);
  //   //     graph.setItemState(edge, "highlight", true);
  //   //     edge.toFront();
  //   //   } else {
  //   //     graph.setItemState(edge, "highlight", false);
  //   //     graph.setItemState(edge, "lineDark", true);
  //   //   }
  //   // });
  //   graph.paint();
  //   graph.setAutoPaint(true);
  // });

  graph.on("canvas:click", clearAllStats);

  if (typeof window !== "undefined") {
    window.onresize = () => {
      if (!graph || graph.get("destroyed")) return;
      const container = document.getElementById("container");
      if (!container) return;
      graph.changeSize(container.clientWidth, container.clientHeight);
    };
  }

  return graph;
};
function refreshDragedNodePosition(e) {
  const model = e.item.get("model");
  model.fx = e.x;
  model.fy = e.y;
}
export const clearAllStats = () => {
  graph.setAutoPaint(false);
  graph.getNodes().forEach((node) => {
    graph.clearItemStates(node);
  });
  graph.getEdges().forEach((edge) => {
    graph.clearItemStates(edge);
  });
  graph.paint();
  graph.setAutoPaint(true);
};

export const setAllStateDark = () => {
  clearAllStats();
  graph.setAutoPaint(false);
  graph.getNodes().forEach((node) => {
    graph.setItemState(node, "dark", true);
  });
  graph.getEdges().forEach((edge) => {
    graph.setItemState(edge, "lineDark", true);
  });
  graph.paint();
  graph.setAutoPaint(true);
};

/** 居中 */
emitter.on("toolbarEvent", (type) => {
  // console.log(toolbar, "graph.value");
  switch (type) {
    case "juzhong":
      toolbar.autoZoom();
      break;
    case "chexiao":
      toolbar.undo();
      break;
    case "huifu":
      toolbar.redo();
      break;
  }
});

/** 还原节点大小 */
export const returnNodeSize = () => {
  graph.getNodes().map((item) => {
    const model = {
      id: item.getModel().id,
      size: 48,
    };
    item.update(model);
  });
};
